home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / BACKUP / SNATCH.ZIP;1 / SNATCH.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-02  |  7.1 KB  |  324 lines

  1. /* ***************************************************************************
  2. **
  3. **    Program reads diskette into a disk file as an image.
  4. **    Disk type is decided by the BPB on the disk.
  5. **
  6. **    Copyright (c) 1988-1990 PFM Engineering
  7. **        Placed in the public domain.
  8. **
  9. **        Use it, abuse it, throw it away, but leave this notice intact.
  10. **        No responsibility whatever is assumed for the suitability
  11. **        of this software.
  12. **
  13. **        Frank Hughes
  14. **        PFM Engineering
  15. **        5331A Williams Rd.
  16. **        Norcross GA 30093
  17. **
  18. **        CIS address: 74505,566
  19. **
  20. **    Compile:    cl -Zp -AL snatch.c
  21. **
  22. **    28 April 1988                    V1.0        FAH
  23. **
  24. **
  25. **    13 July 1988        V1.1
  26. **        Add path specification.
  27. **
  28. **    2 June 1990        V1.2
  29. **        Recompile under C6.0
  30. **
  31. *************************************************************************** */
  32.  
  33. #include    <stdio.h>
  34. #include    <stdlib.h>
  35. #include    <process.h>
  36. #include        <conio.h>
  37. #include        <string.h>
  38. #include        <dos.h>
  39. #include        <malloc.h>
  40. #include    "snatch.h"
  41.  
  42. char Version[15] = "1.2";    /* Version number        */
  43.  
  44. void panic(char *data)
  45. {
  46.     fprintf(stderr, "\n\nsnatch: %s\n", data);
  47.     exit(-1);
  48. }
  49.  
  50. /*
  51.  *      Print usage message.
  52.  *
  53.  */
  54.  
  55. void usage(void)
  56. {
  57.   printf("\n\nVersion: %s\t\tPFM Engineeering\t\t060290\n", Version);
  58.   printf("Usage:\n");
  59.   printf("  snatch drive: [-p file path] [-w]\n\n");
  60.   printf("\tParameters in []'s are optional.\n\tDefaults is diskette read mode into file DISKETTE.IMG\n\n");
  61.   printf("\tfile path:          set filename and path\n");
  62.   printf("\t-w                  set diskette write mode\n\n");
  63.  
  64.   exit(1);
  65. }
  66.  
  67. char Signature[] = "Copyright (c) 1988-1990 PFM Engineering";
  68.  
  69. main( argc, argv)
  70. int argc;
  71. char **argv;
  72. {
  73.     char *Path;
  74.     FILE *f0;
  75.     union REGS regs;
  76.     struct SREGS sregs;
  77.     unsigned char far *DiskBuf;
  78.     BootSector far *SectorZero;
  79.     unsigned SectorPointer, NSectors, TotalSectors;
  80.     unsigned char DiskNumber;
  81.     unsigned char DiskType = 0;
  82.     unsigned char WriteFlag = 0;
  83.  
  84.     if (argc < 2)
  85.       usage();
  86.  
  87.     if ((DiskBuf = (unsigned char far *) calloc(122, 512)) == NULL)
  88.       panic("Memory allocation error");
  89.  
  90.     if ((SectorZero = (BootSector far *) calloc(1, 512)) == NULL)
  91.       panic("Memory allocation error");
  92.  
  93.     if ((Path = (char *) calloc(1, 80)) == NULL)
  94.       panic("Memory allocation error");
  95.  
  96.     strcpy(Path, "diskette.img");   /* Default file name        */
  97.  
  98.     for (argc--, argv++; argc > 0; argc--, argv++) {
  99.       switch(**argv) {
  100.     case '-':
  101.       while (*++(*argv)) {        /* Process all flags in this arg */
  102.         switch (**argv) {
  103.  
  104.           case 'p':
  105.           case 'P':
  106.         argv++;
  107.         argc--;
  108.         strcpy(Path, *argv);    /* Get new filename & path  */
  109.         goto nextarg;
  110.  
  111.           case 'w':
  112.           case 'W':
  113.         WriteFlag = 1;        /* Set write mode        */
  114.         goto nextarg;
  115.  
  116.           case '?':         /* Help message         */
  117.           case 'x':
  118.         usage();
  119.         break;
  120.  
  121.           default:
  122.         fprintf(stderr, "Unknown flag: '%c'\n", **argv);
  123.         usage();
  124.         }
  125.       }
  126.       break;
  127.  
  128.     case 'a':
  129.     case 'A':
  130.       if ((*++(*argv)) != ':')
  131.         usage();
  132.       DiskNumber = 0;
  133.       break;
  134.  
  135.     case 'b':
  136.     case 'B':
  137.       if ((*++(*argv)) != ':')
  138.         usage();
  139.       DiskNumber = 1;
  140.       break;
  141.  
  142.     default:
  143.       usage();
  144.       break;
  145.     }
  146.  
  147. nextarg: continue;
  148.     }
  149.  
  150.     if (!WriteFlag) {
  151.  
  152. /*
  153.  *  Read diskette
  154.  */
  155.       if (DiskType == 0) {    /* Set type from BPB        */
  156.     regs.h.al = DiskNumber;
  157.     regs.x.cx = 1;
  158.     regs.x.dx = 0;
  159.     sregs.ds = FP_SEG(SectorZero);
  160.     regs.x.bx = FP_OFF(SectorZero);
  161.  
  162.     int86x( 0x25, ®s, ®s, &sregs);
  163.  
  164.     printf("Reading ");
  165.     switch(SectorZero->MediaByte) {
  166.       case 0xf0:
  167.         printf("3.5'', 1.44MB diskette\n\n");
  168.         NSectors = 120;        /* 24 cycles        */
  169.         break;
  170.       case 0xfd:
  171.         printf("5.25'', 360KB diskette\n\n");
  172.         NSectors = 120;        /* 6 cycles        */
  173.         break;
  174.       case 0xf9:
  175.         switch(SectorZero->SectorsPerTrack) {
  176.           case 9:
  177.         printf("3.5'', 720KB diskette\n\n");
  178.         NSectors = 120;        /* 12 cycles        */
  179.         break;
  180.  
  181.           case 15:
  182.         printf("5.25'', 1.2MB diskette\n\n");
  183.         NSectors = 120;        /* 20 cycles        */
  184.         break;
  185.  
  186.           default:
  187.         panic("Unknown diskette type detected");
  188.         break;
  189.         }
  190.         break;
  191.  
  192.       default:
  193.         panic("Unknown diskette type detected");
  194.         break;
  195.     }
  196.     TotalSectors = SectorZero->SectorTotal;
  197.       }
  198.  
  199.       if ((f0 = fopen(Path, "wb")) == NULL)
  200.     panic("File open error");
  201.  
  202.       SectorPointer = 0;
  203.       while( SectorPointer < TotalSectors ) {
  204.  
  205.     printf("%d%% complete\r", (int) (((float) SectorPointer / (float) TotalSectors) * 100.00));
  206.  
  207.     regs.h.al = DiskNumber;
  208.     regs.x.cx = NSectors;
  209.     regs.x.dx = SectorPointer;
  210.     sregs.ds = FP_SEG(DiskBuf);
  211.     regs.x.bx = FP_OFF(DiskBuf);
  212.  
  213.     int86x( 0x25, ®s, ®s, &sregs);
  214.  
  215.     if ( regs.x.cflag & 0x01 ) {        /* CY set is error        */
  216.       fclose(f0);
  217.       panic("Diskette read error");
  218.     }
  219.  
  220.     if (fwrite( DiskBuf, 512, NSectors, f0 ) != NSectors) {
  221.       fclose(f0);
  222.       panic("File write error");
  223.     }
  224.  
  225.     SectorPointer += NSectors;
  226.  
  227.       }
  228.  
  229.       printf("Complete.             \n");
  230.       fclose(f0);
  231.     } else {                /* Write a diskette        */
  232.  
  233. /*
  234.  *  Write a diskette.
  235.  */
  236.  
  237.       if ((f0 = fopen(Path, "rb")) == NULL)
  238.     panic("File open error");
  239.  
  240.       if (fread(SectorZero, sizeof(BootSector), 1, f0) != 1)
  241.     panic("File read error");
  242.  
  243.       if (DiskType == 0) {    /* Set type from BPB        */
  244.     printf("Writing ");
  245.     switch(SectorZero->MediaByte) {
  246.       case 0xf0:
  247.         printf("3.5'', 1.44MB diskette\n\n");
  248.         NSectors = 120;        /* 24 cycles        */
  249.         break;
  250.       case 0xfd:
  251.         printf("5.25'', 360KB diskette\n\n");
  252.         NSectors = 120;        /* 6 cycles        */
  253.         break;
  254.       case 0xf9:
  255.         switch(SectorZero->SectorsPerTrack) {
  256.           case 9:
  257.         printf("3.5'', 720KB diskette\n\n");
  258.         NSectors = 120;        /* 12 cycles        */
  259.         break;
  260.  
  261.           case 15:
  262.         printf("5.25'', 1.2MB diskette\n\n");
  263.         NSectors = 120;        /* 20 cycles        */
  264.         break;
  265.  
  266.           default:
  267.         panic("Unknown diskette type detected");
  268.         break;
  269.         }
  270.         break;
  271.  
  272.       default:
  273.         panic("Unknown diskette type detected");
  274.         break;
  275.     }
  276.     TotalSectors = SectorZero->SectorTotal;
  277.       }
  278.  
  279.       if (fseek(f0, 0L, SEEK_SET)) {
  280.     fclose(f0);
  281.     panic("Seek failure");
  282.       }
  283.  
  284.       SectorPointer = 0;
  285.  
  286.       printf("\007WARNING!! The diskette in drive %c: will be overwritten!\n",
  287.          0x41 + DiskNumber);
  288.       printf("Press ENTER to continue.  Any other key aborts.\n");
  289.       if (getch() != 0x0d)
  290.     panic("Operator abort");
  291.  
  292.       printf("\n");
  293.       while( SectorPointer < TotalSectors ) {
  294.  
  295.     printf("%d%% complete\r", (int) (((float) SectorPointer / (float) TotalSectors) * 100.00));
  296.  
  297.     regs.h.al = DiskNumber;
  298.     regs.x.cx = NSectors;
  299.     regs.x.dx = SectorPointer;
  300.     sregs.ds = FP_SEG(DiskBuf);
  301.     regs.x.bx = FP_OFF(DiskBuf);
  302.  
  303.     if (fread( DiskBuf, 512, NSectors, f0 ) != NSectors) {
  304.       fclose(f0);
  305.       panic("File read error");
  306.     }
  307.  
  308.     int86x( 0x26, ®s, ®s, &sregs);
  309.  
  310.     if ( regs.x.cflag & 0x01 ) {        /* CY set is error        */
  311.       fclose(f0);
  312.       panic("Diskette write error");
  313.     }
  314.  
  315.     SectorPointer += NSectors;
  316.  
  317.       }
  318.  
  319.       printf("Complete.             \n");
  320.       fclose(f0);
  321.  
  322.     }
  323. }
  324.